import { ref, nextTick } from 'vue'
import type { Ref } from 'vue'
import { useI18n } from '@/locales/useI18n'
import { message } from 'ant-design-vue'
import { cloneDeep } from 'lodash-es'
import {
  useModal as useBasicModal,
  ModalProps,
  RegisterFn
} from '@/components/Modal'

const { t } = useI18n()

interface ModalOptions extends ModalProps {
  maxHeight?: String | number
  isAuto?: Boolean
}

interface ReturnMethods {
  onClose: () => void
  onShow: (row?: any) => void
  getInnerForm: (validateForm: PromiseFn) => Promise<any>
}

export type UseModalReturnType<T> = [
  RegisterFn,
  ReturnMethods,
  Ref<T | undefined>
]

export function useModal<T = any>(
  bind: ModalOptions = {}
): UseModalReturnType<T> {
  const [register, { openModal, closeModal: onClose, setModalProps }] =
    useBasicModal()

  const { maxHeight, isAuto, bodyStyle, ...options } = Object.assign(
    {
      maxHeight: '70vh',
      bodyStyle: { padding: 0 },
      isAuto: true
    },
    bind
  )

  const bodyHeight = isAuto ? { overflow: 'auto', maxHeight } : {}

  const bindValue = {
    destroyOnClose: true,
    width: '45%',
    bodyStyle: bodyStyle ? Object.assign(bodyStyle, bodyHeight) : bodyHeight,
    okText: t('system.actions.confirm'),
    cancelText: t('system.actions.cancel'),
    ...options
  }

  nextTick(() => {
    setModalProps(bindValue)
  })

  const currentItem = ref<T>()

  const getInnerForm = function (validateFormFn: PromiseFn) {
    return validateFormFn().catch((err: any) => {
      message.warning(t('system.form.warning'))
      return Promise.reject(err)
    })
  }

  const onShow = function (row?: T) {
    if (row) {
      currentItem.value = cloneDeep(row)
    }
    openModal()
  }

  return [register, { onClose, onShow, getInnerForm }, currentItem]
}

export default useModal